﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using Microsoft.Devices;
using System.Windows.Media;
using SharpDepend.Classes.ProfileredDatatypes.Collections.Generic;

namespace SharpDepend.WP8
{
    class CameraManager : ICameraManager
    {
        class Camera : ICamera
        {
            private CameraType mCameraType;
            private PhotoCamera mCamera;
            private VideoBrush mVideoBrush;
            private bool mInitialized;

            public Camera(CameraType cameraType)
            {
                mCameraType = cameraType;
                Name = cameraType.ToString();
            }

            private void MCamera_Initialized(object sender, CameraOperationCompletedEventArgs e)
            {
                mInitialized = e.Succeeded;
            }

            public string Name { get; private set; }

            public int PixelHeight
            {
                get
                {
                    return (int)mCamera.PreviewResolution.Width;
                }
            }

            public int PixelWidth
            {
                get
                {
                    return (int)mCamera.PreviewResolution.Height;
                }
            }

            public bool Ready { get { return mInitialized; } }

            public void GetPreviewBuffer(int[] data)
            {
                if (mInitialized)
                {
                    mCamera.GetPreviewBufferArgb32(data);
                }
            }

            public void StartPreview()
            {
                if (mVideoBrush != null)
                {
                    throw new InvalidOperationException("Camera can only start once. It must be stopped first.");
                }

                mVideoBrush = new VideoBrush();
                mCamera = new PhotoCamera(mCameraType);
                mCamera.Initialized += MCamera_Initialized;
                mVideoBrush.SetSource(mCamera);
            }

            public void StopPreview()
            {
                if (mVideoBrush == null)
                {
                    throw new InvalidOperationException("Camera is already stopped.");
                }

                mInitialized = false;
                mCamera.Initialized -= MCamera_Initialized;
                mCamera = null;
                mVideoBrush = null;
                GC.Collect();
            }
        }

        private PList<Camera> mAvailableCameras;

        public CameraManager()
        {
            mAvailableCameras = new PList<Camera>("Cameras", this);
            mAvailableCameras.Add(new Camera(CameraType.Primary));
            mAvailableCameras.Add(new Camera(CameraType.FrontFacing));
        }

        public IEnumerable<ICamera> AvailableCameras
        {
            get
            {
                return mAvailableCameras;
            }
        }
    }
}
